# cd python/src && python AccessTokenTest.py
import sys
import os
from flask import Flask, request, jsonify
import time
from flask_cors import CORS


import datetime
import hashlib
import hmac
from urllib.parse import quote

import requests
import json

from typing import List
from alibabacloud_ocr_api20210707.client import Client as ocr_api20210707Client
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_ocr_api20210707 import models as ocr_api_20210707_models
from alibabacloud_tea_util import models as util_models
from alibabacloud_tea_console.client import Client as ConsoleClient
from alibabacloud_tea_util.client import Client as UtilClient
import io


sys.path.append(os.path.join(os.path.dirname(__file__), '../server'))
import AccessToken


app = Flask(__name__)
CORS(app)

# 获取用户token
@app.route('/generateToken', methods=['POST'])
def generate_token():
    data = request.json
    if not data or 'room_id' not in data or 'user_id' not in data:
        return jsonify({'error': 'Missing required fields'}), 400

    # 提取数据
    app_id = "67d26abfd8adba017d30dd50"
    app_key = "242a1d2c3083467a9fedfacf52f92d95"
    
    room_id = data['room_id']
    user_id = data['user_id']
    token = AccessToken.AccessToken(app_id, app_key, room_id, user_id)
    token.add_privilege(AccessToken.PrivSubscribeStream, 0)
    token.add_privilege(AccessToken.PrivPublishStream, int(time.time()) + 3600)
    token.expire_time(int(time.time()) + 3600)
    s = token.serialize()
    t = AccessToken.parse(s)
    print("appId:"+token.app_id)
    print("appKey:"+token.app_key)
    print(t.verify(app_key))
    print(s)

    # 返回生成的 token
    return jsonify({'token': s}), 200


UPLOAD_FOLDER = 'uploads'
if not os.path.exists(UPLOAD_FOLDER):
    os.makedirs(UPLOAD_FOLDER)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 

config = open_api_models.Config(
            access_key_id="LTAI5t5aKcX6SPTpHFxiiNjF",
            access_key_secret="9sII0nIIBmSGmaB0wHrrBkouFeLQUU")
config.endpoint = f'ocr-api.cn-hangzhou.aliyuncs.com'
ocrclient = ocr_api20210707Client(config)

@app.route('/upload', methods=['POST'])
def upload_file():
    if 'file' not in request.files:
        return jsonify({'error': 'No file part in the request'}), 400

    file = request.files['file']

    if file.filename == '':
        return jsonify({'error': 'No file selected for uploading'}), 400

    # 保存文件到本地
    if file:
        file_path = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)
        file.save(file_path)   
        
        with open(file_path, 'rb') as image_file:
            image_data = image_file.read()
        
        image_binary = io.BytesIO(image_data)
        
        recognize_edu_paper_cut_request = ocr_api_20210707_models.RecognizeEduPaperStructedRequest(
            # url="",
            need_rotate=False,
            body=image_binary,
            # cut_type="question",
            # image_type="photo",
            # subject="default",
            # output_oricoord=True
        )
        runtime = util_models.RuntimeOptions()
        try:
            resp = ocrclient.recognize_edu_paper_structed_with_options(recognize_edu_paper_cut_request, runtime)
            print(resp.headers)
            # print(resp.statusCode)
            # print(resp.body)
            # ConsoleClient.log(UtilClient.to_jsonstring(resp))
            response_map = resp.body.to_map()
            return jsonify({'message': 'File uploaded successfully', 'result': response_map}), 200
        except Exception as error:
            print(error.message)
            print(error.data.get("Recommend"))
            UtilClient.assert_as_string(error.message)
          
    return jsonify({'message': 'analysis failed', 'result': {}}), 200    



AK = "AKLTMzAxMDAyZTczOTNmNDJhZmIyZjM5NWIzNjkyYzUxMGY"
SK = "WVRVMk9UWXhPV1V3WTJaaU5HVTNNemxsWWpsa01tWTNaR1UwTmpGbVpqUQ=="

Service = "rtc"
Version = "2024-12-01"
Region = "cn-north-1"
Host = "rtc.volcengineapi.com" #iam.volcengineapi.com
ContentType = "application/json"

def norm_query(params):
    query = ""
    for key in sorted(params.keys()):
        if type(params[key]) == list:
            for k in params[key]:
                query = (
                        query + quote(key, safe="-_.~") + "=" + quote(k, safe="-_.~") + "&"
                )
        else:
            query = (query + quote(key, safe="-_.~") + "=" + quote(params[key], safe="-_.~") + "&")
    query = query[:-1]
    return query.replace("+", "%20")

# 第一步：准备辅助函数。
# sha256 非对称加密
def hmac_sha256(key: bytes, content: str):
    return hmac.new(key, content.encode("utf-8"), hashlib.sha256).digest()


# sha256 hash算法
def hash_sha256(content: str):
    return hashlib.sha256(content.encode("utf-8")).hexdigest()


def customRequest(method, date, query, header, ak, sk, action, body):
    # 第三步：创建身份证明。其中的 Service 和 Region 字段是固定的。ak 和 sk 分别代表
    # AccessKeyID 和 SecretAccessKey。同时需要初始化签名结构体。一些签名计算时需要的属性也在这里处理。
    # 初始化身份证明结构体
    credential = {
        "access_key_id": ak,
        "secret_access_key": sk,
        "service": Service,
        "region": Region,
    }
    # 初始化签名结构体
    request_param = {
        "body": body,
        "host": Host,
        "path": "/",
        "method": method,
        "content_type": ContentType,
        "date": date,
        "query": {"Action": action, "Version": Version, **query},
    }
    if body is None:
        request_param["body"] = ""
    # 第四步：接下来开始计算签名。在计算签名前，先准备好用于接收签算结果的 signResult 变量，并设置一些参数。
    # 初始化签名结果的结构体
    x_date = request_param["date"].strftime("%Y%m%dT%H%M%SZ")
    short_x_date = x_date[:8]
    x_content_sha256 = hash_sha256(request_param["body"])
    sign_result = {
        "Host": request_param["host"],
        "X-Content-Sha256": x_content_sha256,
        "X-Date": x_date,
        "Content-Type": request_param["content_type"],
    }
    # 第五步：计算 Signature 签名。
    signed_headers_str = ";".join(
        ["content-type", "host", "x-content-sha256", "x-date"]
    )
    # signed_headers_str = signed_headers_str + ";x-security-token"
    canonical_request_str = "\n".join(
        [request_param["method"].upper(),
         request_param["path"],
         norm_query(request_param["query"]),
         "\n".join(
             [
                 "content-type:" + request_param["content_type"],
                 "host:" + request_param["host"],
                 "x-content-sha256:" + x_content_sha256,
                 "x-date:" + x_date,
             ]
         ),
         "",
         signed_headers_str,
         x_content_sha256,
         ]
    )

    # 打印正规化的请求用于调试比对
    print(canonical_request_str)
    hashed_canonical_request = hash_sha256(canonical_request_str)

    # 打印hash值用于调试比对
    print(hashed_canonical_request)
    credential_scope = "/".join([short_x_date, credential["region"], credential["service"], "request"])
    string_to_sign = "\n".join(["HMAC-SHA256", x_date, credential_scope, hashed_canonical_request])

    # 打印最终计算的签名字符串用于调试比对
    print(string_to_sign)
    k_date = hmac_sha256(credential["secret_access_key"].encode("utf-8"), short_x_date)
    k_region = hmac_sha256(k_date, credential["region"])
    k_service = hmac_sha256(k_region, credential["service"])
    k_signing = hmac_sha256(k_service, "request")
    signature = hmac_sha256(k_signing, string_to_sign).hex()

    sign_result["Authorization"] = "HMAC-SHA256 Credential={}, SignedHeaders={}, Signature={}".format(
        credential["access_key_id"] + "/" + credential_scope,
        signed_headers_str,
        signature,
    )
    header = {**header, **sign_result}
    # header = {**header, **{"X-Security-Token": SessionToken}}
    # 第六步：将 Signature 签名写入 HTTP Header 中，并发送 HTTP 请求。
    r = requests.request(method=method,
                         url="https://{}{}".format(request_param["host"], request_param["path"]),
                         headers=header,
                         params=request_param["query"],
                         data=request_param["body"],
                         )
    return r.json()


@app.route('/robotAction', methods=['POST'])
def register_robot():
    data = request.json
    action = request.args.get('Action')
    version = request.args.get('Version')
    # print("\n\nAction:"+action+"\n\n")
    # print("\nVersion:"+version+"\n\n")
    # print("\n\n请求的json:"+str(data)+"\n\n")
    
    response = customRequest("POST",datetime.datetime.utcnow(),
        {"Action":action, "Version":version},
        {"Content-Type": "application/json"}, AK, SK, action, json.dumps(data)
    )
    print(response)
    
    if response['Result'] == 'ok':
        return jsonify({'status': 'success', 'content': json.dumps(response)}), 200
    else:
        return jsonify({'status': 'error', 'content': json.dumps(response)}), 500



if __name__ == '__main__':
    # now = datetime.datetime.utcnow()
    # # Body的格式需要配合Content-Type，API使用的类型请阅读具体的官方文档，如:json格式需要json.dumps(obj)
    # response_body = customRequest("GET", now, {"Limit": "2"}, {}, AK, SK, "ListUsers", None)
    # print(response_body)

    # response_body = customRequest("POST", now, {"Limit": "10"}, {}, AK, SK, "ListUsers", "UnUseParam=ASDF")
    # print(response_body)
    
    app.run(host='0.0.0.0', port=5000)


    







